/**
**********************************************************************
* @file     main.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2022-05-04 13:58:26
* @copyright Copyright &copy; 2022 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
**********************************************************************
* @note
* None.
**********************************************************************
* @attention
* None.
**********************************************************************
@verbatim
@endverbatim
**********************************************************************
* @par 历史记录
* 1. v0.0.1: jcai, 2022-05-04 13:58:26
*   - 首次编写
*
*<center>Copyright &copy; 2022 wy1107412334@163.com All rights reserved</center>
**********************************************************************
*/

/* 头文件导入区 --------------------------------------------------- */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_video.h>
#include <SDL/SDL_ttf.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_events.h>
#include <SDL/SDL_timer.h>
#include <SDL/SDL_keysym.h>
#include <SDL/SDL_keyboard.h>

#define STRING_INIT_LEN 20
typedef struct
{
    char *str;  // 保存输入的字符串
    uint32_t totalsize; // str指向的内存空间实际大小
    uint32_t length;    // str指向的字符串的实际长度
    SDL_Surface *text;
} StringInput_t;


// 窗口属性
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

// 将要使用的表面
SDL_Surface *background = NULL;
SDL_Surface *message = NULL;
SDL_Surface *screen = NULL;

// 事件结构体
SDL_Event event;

// 使用的字体
TTF_Font *font;
// 字体颜色
SDL_Color textColor = {0xff, 0xff, 0xff};



SDL_Surface *load_image(const char *file)
{
    SDL_Surface *loadedImage = NULL;
    SDL_Surface *optimizedImage = NULL;

    // 通过 SDL_imag 模块加载图片
    loadedImage = IMG_Load(file);
    if (!loadedImage)   return NULL;

    optimizedImage = SDL_DisplayFormat(loadedImage);
    SDL_FreeSurface(loadedImage);
    if (optimizedImage)
    {
        // 映射关键色
        uint32_t keycolor = SDL_MapRGB(optimizedImage->format, 0, 0xff, 0xff);
        // 将所有颜色为 RGB(0x00, 0xff, 0xff) 的像素设为透明
        SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, keycolor);
    }

    return optimizedImage;
}

void apply_surface(int x, int y, SDL_Surface *src, SDL_Surface *dst)
{
    SDL_Rect offset;

    offset.x = x;
    offset.y = y;

    SDL_BlitSurface(src, NULL, dst, &offset);
}

int init()
{
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
        return -1;

    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
                              SDL_SWSURFACE);
    if (!screen)
    {
        SDL_Quit();
        return -2;
    }

    if (TTF_Init() == -1)
    {
        SDL_Quit();
        return -3;
    }

    SDL_WM_SetCaption("High Score", NULL);

    // 给窗口背景填充白色
    SDL_FillRect(screen, &screen->clip_rect,
                 SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));

    return 0;
}

int load_files()
{
    // 加载背景图片
    background = load_image("background.png");
    if (!background) return -1;

    font = TTF_OpenFont("lazy.ttf", 42);
    if (!font)
    {
        SDL_FreeSurface(background);
        return -2;
    }

    return 0;
}

void clean_up()
{
    SDL_FreeSurface(background);

    TTF_CloseFont(font);
    TTF_Quit();

    SDL_Quit();
}


int StringInput_Init(StringInput_t *si)
{
    si->str = malloc(sizeof(char) * STRING_INIT_LEN);
    if (!si->str)   return -1;
    *si->str = '\0';
    si->totalsize = STRING_INIT_LEN;
    si->length = 0;
    si->text = NULL;

    // 启用UNICODE
    SDL_EnableUNICODE(SDL_ENABLE);
    return 0;
}
void StringInput_Uninit(StringInput_t *si)
{
    if (si->str)
    {
        free(si->str);
        si->str = NULL;
        si->totalsize = si->length = 0;
    }
    if (si->text)
    {
        SDL_FreeSurface(si->text);
        si->text = NULL;
    }
    SDL_EnableUNICODE(SDL_DISABLE);
}
void StringInput_handle_input(StringInput_t *si)
{
    if (event.type == SDL_KEYDOWN)
    {
        uint32_t oldlen = si->length;
        uint16_t key = event.key.keysym.unicode;

        if ((si->length + 1) == si->totalsize)
        {
            char *t = realloc(si->str, si->totalsize * 2);
            if (!t) return;
            si->str = t;
            si->totalsize *= 2;
        }

        // 如果按下的是空格键, 数字，大写字母，小写字母
        if ((key == (uint16_t)' ') ||
            ((key >= (uint16_t)'0') && (key <= (uint16_t)'9')) ||
            ((key >= (uint16_t)'A') && (key <= (uint16_t)'Z')) ||
            ((key >= (uint16_t)'a') && (key <= (uint16_t)'z')))
        {
            *(si->str + si->length++) = (uint8_t)key;
            *(si->str + si->length) = '\0';
        }

        // 如果按下的是退格键
        if ((key == SDLK_BACKSPACE) && (si->length))
        {
            *(si->str + si->length - 1) = '\0';
            si->length--;
        }

        if (oldlen != si->length)
        {
            SDL_Surface *newtext = TTF_RenderText_Solid(font, si->str,
                                                        textColor);
            if (!newtext)   return;

            SDL_FreeSurface(si->text);
            si->text = newtext;
        }
    }
}
void StringInput_show(const StringInput_t *si)
{
    if (si->text)
    {
        apply_surface((SCREEN_WIDTH - si->text->w) / 2,
                      (SCREEN_HEIGHT -si->text->h) / 2,
                      si->text,
                      screen);
    }
}


/**
**********************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
int main(int argc, char *argv[])
{
    StringInput_t name;
    int quit = 0;
    int nameEntered = 0;

    if (init() != 0)
    {
        fprintf(stderr, "SDL初始化失败\n");
        return EXIT_FAILURE;
    }
    if (load_files() != 0)
    {
        fprintf(stderr, "SDL加载 background.png 失败\n");
        return EXIT_FAILURE;
    }

    StringInput_Init(&name);

    message = TTF_RenderText_Solid(font, "New High Score! Enter Name:",
                                   textColor);

    while (!quit)
    {
        // 处理SDL的事件
        while (SDL_PollEvent(&event))
        {
            if (!nameEntered)
            {
                StringInput_handle_input(&name);

                // 如果回车键被按下
                if ((event.type == SDL_KEYDOWN) &&
                    (event.key.keysym.sym == SDLK_RETURN))
                {
                    nameEntered = 1;
                    SDL_FreeSurface(message);
                    message = TTF_RenderText_Solid(font, "Rank: 1st",
                                                   textColor);
                }
                //
            }

            // 如果用户点击了窗口右上角的关闭按钮
            if (event.type == SDL_QUIT)
            {
                quit = 1;
                printf("处理退出事件\n");
            }
        }

        // 显示背景图
        apply_surface(0, 0, background, screen);

        // 显示提示信息
        apply_surface((SCREEN_WIDTH - message->w) / 2,
                      (SCREEN_HEIGHT / 2 - message->h) / 2,
                      message,
                      screen);

        // 显示输入的字符串
        StringInput_show(&name);

        // 更新窗口
        if (SDL_Flip(screen) == -1)
        {
            fprintf(stderr, "SDL更新窗口失败\n");
            break;
        }
    }

    StringInput_Uninit(&name);
    clean_up();

    return 0;
}




/***  Copyright (C) 2022 wy1107412334@163.com All rights reserved ***/
/****************************** END OF FILE *************************/

